-- 单片机调试需要手动修改可执行文件名，并确保工程路径正确
-- 手动方式，已添加自动方式查找elf, 需要在build目录下
-- 配置待优化
local mcu_elf_name = "test.elf"

return {
  "mfussenegger/nvim-dap",
  optional = true,
  dependencies = {
    -- Ensure C/C++ debugger is installed
    "williamboman/mason.nvim",
    optional = true,
    opts = function(_, opts)
      if type(opts.ensure_installed) == "table" then
        vim.list_extend(opts.ensure_installed, { "codelldb", "cpptools" })
      end
    end,
  },
  opts = function()
    local dap = require("dap")

    dap.set_log_level("debug")

    if not dap.adapters["codelldb"] then
      require("dap").adapters["codelldb"] = {
        type = "server",
        host = "localhost",
        port = "${port}",
        executable = {
          command = "codelldb",
          args = {
            "--port",
            "${port}",
          },
        },
      }
    end

    local mason_path = vim.fn.glob(vim.fn.stdpath("data")) .. "/mason/"
    local cppdbg_exec_path = mason_path .. "packages/cpptools/extension/debugAdapters/bin/OpenDebugAD7"
    --local codelldb_exec_path = mason_path .. "packages/codelldb/extension/adapter/codelldb"
    --local cortex_debug_exec_path = mason_path .. "packages/cortex-debug/extension/dist/debugadapter.js"
    local elf_dir = vim.fn.getcwd() .. "/build"
    local elf_dir_file_table = vim.fn.readdir(elf_dir)
    local elf_files = {}
    local elf_file_name

    local function find_elf_name()
      elf_files = {}
      for _, file in ipairs(elf_dir_file_table) do
        if file:match("%.elf$") then
          table.insert(elf_files, elf_dir .. "/" .. file)
        end
      end

      if #elf_files == 1 then
        elf_file_name = elf_files[1]
        -- print(elf_file_name)
        return elf_files[1]
      elseif #elf_files > 1 then
        vim.fn.inputlist(elf_files)
        local choice = vim.fn.input("Choose ELF file number[1][2][3]...: ")
        elf_file_name = elf_files[tonumber(choice)]
        return elf_files[tonumber(choice)]
      else
        print("No ELF file found in build directory")
        return nil
      end
    end

    local function get_elfname()
      return elf_file_name
    end

    if not dap.adapters["cppdbg"] then
      require("dap").adapters["cppdbg"] = {
        id = "cppdbg",
        type = "executable",
        command = cppdbg_exec_path,
        args = {},
      }
    end

    for _, lang in ipairs({ "c", "cpp" }) do
      dap.configurations[lang] = {
        {
          type = "codelldb",
          request = "launch",
          name = "Launch file",
          program = function()
            return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file")
          end,
          cwd = "${workspaceFolder}",
        },
        {
          type = "codelldb",
          request = "attach",
          name = "Attach to process",
          pid = require("dap.utils").pick_process,
          cwd = "${workspaceFolder}",
        },
        -------------------------------------MCU----------------------------------------------
        {
          find_elf_name(),
          name = "[mcu][WorkSpaceCFG]",
          type = "cppdbg",
          request = "launch",
          -- program = get_s(),
          program = function()
            local elf = get_elfname()
            if elf then
              return elf
            else
              print("cppdbg: No ELF file found in build directory")
              return nil
            end
          end,
          cwd = "${workspaceFolder}",
          miMode = "gdb",
          miDebuggerPath = "arm-none-eabi-gdb", -- 确保 GDB 在系统路径中
          miDebuggerServerAddress = "localhost:3333",
          useExtendedRemote = true,

          preLaunchTask = function()
            os.execute("pkill openocd")
            os.execute("sleep 0.1")
            os.execute("openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg > openocd.log 2>1&1")
          end,
          postRemoteConnectCommands = {
            {
              text = "monitor reset halt",
              description = "mcu reset halt",
              ignoreFailures = false,
            },
            {
              text = "load " .. get_elfname(),
              description = "load elf",
              ignoreFailures = false,
            },
            {
              text = "monitor reset init",
              description = "mcu reset halt",
              ignoreFailures = false,
            },
          },
          stopAtEntry = false,
          runInTerminal = false,
          externalConsole = false,
          svdPath = "${workspaceFolder}/STM32F103.svd",
          showDevDebugOutput = "raw",
        },
        -----------------------------------------------------------------------------------
        {
          name = "[mcu][stlinkv2][stm32f1x]",
          type = "cppdbg",
          request = "launch",
          program = "${workspaceFolder}/build/" .. mcu_elf_name, -- 修改为实际的 ELF 文件路径
          -- program = function()
          --   return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/build/", "file")
          -- end,
          cwd = "${workspaceFolder}",
          miMode = "gdb",
          miDebuggerPath = "arm-none-eabi-gdb", -- 确保 GDB 在系统路径中
          miDebuggerServerAddress = "localhost:3333",
          postRemoteConnectCommands = {
            {
              text = "load build/" .. mcu_elf_name,
            },
            {
              text = "monitor reset halt",
            },
          },
          setupCommands = {
            {
              description = "Enable pretty-printing",
              text = "-enable-pretty-printing",
              ignoreFailures = true,
            },
          },
          preLaunchTask = function()
            os.execute("pkill openocd")
            os.execute("openocd -f interface/stlink.cfg -f target/stm32f1x.cfg > openocd.log 2>1&1")
          end,
          stopAtEntry = false,
          runInTerminal = false,
          externalConsole = false,
          svdPath = "${workspaceFolder}/STM32F103.svd",
          --showDevDebugOutput = "raw",
        },
        {
          name = "[mcu][daplink][stm32f1x]",
          type = "cppdbg",
          request = "launch",
          program = "${workspaceFolder}/build/" .. mcu_elf_name, -- 修改为实际的 ELF 文件路径
          -- program = function()
          --   return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/build/", "file")
          -- end,
          cwd = "${workspaceFolder}",
          miMode = "gdb",
          miDebuggerPath = "arm-none-eabi-gdb", -- 确保 GDB 在系统路径中
          miDebuggerServerAddress = "localhost:3333",
          postRemoteConnectCommands = {
            {
              text = "load build/" .. mcu_elf_name,
            },
            {
              text = "monitor reset halt",
            },
          },
          setupCommands = {
            {
              description = "Enable pretty-printing",
              text = "-enable-pretty-printing",
              ignoreFailures = true,
            },
          },
          preLaunchTask = function()
            os.execute("pkill openocd")
            os.execute("openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg > openocd.log 2>1&1")
          end,
          stopAtEntry = false,
          runInTerminal = false,
          externalConsole = false,
          svdPath = "${workspaceFolder}/STM32F103.svd",
          --showDevDebugOutput = "raw",
        },
      }
    end
  end,
}
